/**
 * Created by Yu Jin Xian on 2017/1/9.
 */
function prototypeChaining() {
    function SuperType() {
        this.property = true;
    }

    SuperType.prototype.getSuperValue = function () {
        return this.property;
    };

    function SubType() {
        this.subproperty = false;
    }

    // 继承了 SuperType
    SubType.prototype = new SuperType();

    SubType.prototype.getSubvalue = function () {
        return this.subproperty;
    };

    var instance = new SubType();
    alert(instance.getSuperValue());                // true

    alert(instance instanceof Object);              // true
    alert(instance instanceof SuperType);           // true
    alert(instance instanceof SubType);             // true

    alert(Object.prototype.isPrototypeOf(instance));    // true
    alert(SuperType.prototype.isPrototypeOf(instance)); // true
    alert(SubType.prototype.isPrototypeOf(instance));   // true

    function cautiousDefinedMethods() {
        function SubType() {
            this.property = true;
        }

        SuperType.prototype.getSuperValue = function () {
            return this.property;
        };

        // 继承了 SuperType
        SubType.prototype = new SuperType();

        SubType.prototype.getSubvalue = function () {
            return this.subproperty;
        };

        // 重写超类型的中的方法
        SubType.prototype.getSuperValue = function () {
            return false;
        };

        var instance = new SubType();
        alert(instance.getSuperValue());            // false
    }

    function overwritePrototypeChaining() {
        function SubType() {
            this.property = true;
        }

        SuperType.prototype.getSuperValue = function () {
            return this.property;
        };

        // 继承了 SuperType
        SubType.prototype = new SuperType();

        // 使用字面量添加新方法, 会导致上一行代码无效
        SubType.prototype.getSubvalue = {
            getSubValue: function () {
                return this.subproperty;
            },
            someOtherMethod: function () {
                return false;
            }
        };

        var instance = new SubType();
        alert(instance.getSuperValue());            // error!
    }
}

function constructorStealing() {
    function SuperType() {
        this.colors = ['rad', 'blue', 'green'];
    }

    function SubType() {
        // 继承 SuperType
        SuperType.call(this);
    }

    var instance1 = new SubType();
    instance1.colors.push('black');
    alert(instance1.colors);                        // "red,blue,green,black"

    var instance2 = new SubType();
    alert(instance2.colors);                        // "red,blue,green"

    function passParameter() {
        function SuperType(name) {
            this.name = name;
        }

        function SubType() {
            // 继承了 SuperType, 同时还传递了参数
            SuperType.call(this, 'Nicholas');

            this.age = 29;
        }

        var instance = new SubType();
        alert(instance.name);                       // "Nicholas"
        alert(instance.age);                        // 29
    }
}

function combinationInheritance() {
    function SuperType(name) {
        this.name = name;
        this.colors = ['rad', 'blue', 'green'];
    }

    SuperType.prototype.sayName = function () {
        alert(this.name);
    };

    function SubType(name, age) {
        // 继承属性
        SuperType.call(this, name);
        this.age = age;
    }

    // 继承方法
    SubType.prototype = new SuperType();
    SubType.prototype.constructor = SubType;
    SubType.prototype.sayAge = function () {
        alert(this.age);
    };

    var instance1 = new SubType('Nicholas', 29);
    instance1.colors.push('black');
    alert(instance1.colors);                         // "red,blue,green,black"
    instance1.sayName();                             // "Nicholas"
    instance1.sayAge();                              // 29

    var instance2 = new SubType('Greg', 27);
    alert(instance2.colors);                        // "red,blue,green"
    instance2.sayName();                            // "Greg"
    instance2.sayAge();                             // 27
}

function prototypalInheritance() {

}

function parasiticInheritance() {

}

function parasiticCombinationInheritance() {

}